package com.dykj.fireFighting.server.base.news.service.impl;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsRequest;
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsResponse;
import com.aliyuncs.dyvmsapi.model.v20170525.SingleCallByTtsRequest;
import com.aliyuncs.dyvmsapi.model.v20170525.SingleCallByTtsResponse;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.http.MethodType;
import com.aliyuncs.profile.DefaultProfile;
import com.aliyuncs.profile.IClientProfile;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.dykj.fireFighting.api.base.emergency.entity.EmergencyStaff;
import com.dykj.fireFighting.api.base.news.dto.AliMessageDto;
import com.dykj.fireFighting.api.base.news.entity.AliMessage;
import com.dykj.fireFighting.api.base.news.service.IAliMessageService;
import com.dykj.fireFighting.common.core.service.impl.BaseServiceImpl;
import com.dykj.fireFighting.common.core.utils.UUIDUtils;
import com.dykj.fireFighting.common.core.vo.PageVo;
import com.dykj.fireFighting.common.starter.redis.service.RedisService;
import com.dykj.fireFighting.server.base.news.mapper.AliMessageMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.transaction.annotation.Transactional;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Slf4j
@DubboService
@Transactional(rollbackFor = Exception.class)
public class AliMessageServiceImpl extends BaseServiceImpl<AliMessageMapper, AliMessage> implements IAliMessageService {

    @Value("${baidu.accessKeyId}")
    private String accessKeyId;
    @Value("${baidu.accessKeySecret}")
    private String accessKeySecret;
    @Value("${baidu.signName}")
    private String accessSignName;
    @Value("${baidu.templateCode}")
    private String accessTemplateCode;
    @Value("${baidu.coordType}")
    private String accessCoordType;
    @Value("${baidu.redirectUrl}")
    private String accessRedirectUrl;

    @Autowired
    private RedisService redisService;
    @Autowired
    private AliMessageMapper aliMessageMapper;

    //阿里云短信平台短息秘钥
    private String keyId = "LTAI4FpLHF4yZVpZD8D7jMov";
    //阿里云短信平台短息秘钥
    private String keySecret = "bBOqyBv0qYxyu6xwuTl1tJdJsV3pyE";


    @Override
    public String sendFireMessage(String socialName, String socialLocation, String socialAddress, String ztfssj, String name, String location, String phone, String deviceName) throws UnsupportedEncodingException {

        String rs = RandomStringUtils.randomAlphanumeric(3);
        String locations = location + "|name:" + URLEncoder.encode(name,"utf8");
        String destinations = socialLocation + "|name:" + URLEncoder.encode(socialName,"utf8");
        String coordType = accessCoordType;
        String redirectUrl = accessRedirectUrl + rs;
        //百度地图
        String ts= URLEncoder.encode("唐山","utf8");

        String baiduUrl = "http://api.map.baidu.com/direction?origin=latlng:" + locations + "&destination=" + destinations + "&mode=driving&region="+ts+"&coord_type=" + coordType + "&output=html&src=webapp.baidu.openAPIdemo";
        log.info("百度地图url:" + baiduUrl);
        String param = "{\"address\":\"" + socialAddress + "\",\"unitName\":\"" + socialName + "\",\"time\":\"" + ztfssj + "\",\"code\":\"" + rs + "\"}";
        log.info("火情短信内容:" + param);
        // 存入redis
        redisService.set(rs, baiduUrl, 86400L);
        SendSmsResponse sendSmsResponse = sendSmsRequest(param, phone, null, null, null, null);
        return sendSmsResponse.getCode();
    }


    @Override
    public int sendAliMessage(String phone, String signName, String templateCode, String unitName, String device, String time,String unitid,String receiver,String componentStatus) {
        //设置超时时间-可自行调整
        System.setProperty("sun.net.client.defaultConnectTimeout", "10000");
        System.setProperty("sun.net.client.defaultReadTimeout", "10000");

        //初始化ascClient需要的几个参数
        final String product = "Dysmsapi";//短信API产品名称（短信产品名固定，无需修改）

        final String domain = "dysmsapi.aliyuncs.com";//短信API产品域名（接口地址固定，无需修改）

        final String accessKeyId = keyId;//你的accessKeyId

        final String accessKeySecret = keySecret;//你的accessKeySecret

        if (StringUtils.isBlank(signName)) {
            signName = accessSignName;
        }

        if (StringUtils.isBlank(templateCode)) {
            templateCode = accessTemplateCode;
        }

        //初始化ascClient,暂时不支持多region（请勿修改）
        IClientProfile profile = DefaultProfile.getProfile("cn-hangzhou", accessKeyId, accessKeySecret);

        try {
            DefaultProfile.addEndpoint("cn-hangzhou", "cn-hangzhou", product, domain);
        } catch (ClientException e) {
            e.printStackTrace();
        }

        IAcsClient acsClient = new DefaultAcsClient(profile);
        //组装请求对象
        SendSmsRequest request = new SendSmsRequest();
        //使用post提交
        request.setMethod(MethodType.POST);
        //必填:待发送手机号。支持以逗号分隔的形式进行批量调用，批量上限为1000个手机号码,批量调用相对于单条调用及时性稍有延迟,验证码类型的短信推荐使用单条调用的方式；发送国际/港澳台消息时，接收号码格式为00+国际区号+号码，如“0085200000000”
        request.setPhoneNumbers(phone);
        //必填:短信签名-可在短信控制台中找到
        request.setSignName(signName);
        //必填:短信模板-可在短信控制台中找到，发送国际/港澳台消息时，请使用国际/港澳台短信模版
        request.setTemplateCode(templateCode);

        String param = "";
        if (templateCode.equals("SMS_213772600")) {
            param = "{\"device\":\"" + unitName + "\",\"content\":\"" + device + "\",\"time\":\"" + time + "\",\"alarm\":\""+componentStatus+"\"}";
        }else {
            param = "{\"device\":\"" + unitName + "\",\"content\":\"" + device + "\",\"time\":\"" + time + "\"}";
        }
        request.setTemplateParam(param);

        //请求失败这里会抛ClientException异常
        SendSmsResponse sendSmsResponse = null;
        try {
            sendSmsResponse = acsClient.getAcsResponse(request);
            log.info("火情短信发送:" + sendSmsResponse.getMessage());
        } catch (ClientException e) {
            e.printStackTrace();
        }
        System.out.println(sendSmsResponse.getMessage());

        if (sendSmsResponse.getCode() != null && sendSmsResponse.getCode().equals("OK")) {
            //请求成功
            System.out.println("=====success====");
            String message = "尊敬的用户您好，贵单位" + unitName + "的" + device + "于今天" + time + "发生警情，请确认。";
            String messageWaterAlarm = "尊敬的用户您好，贵单位" + unitName + "的" + device + "于今天" + time + "发生"+componentStatus+",请确认。";
            String messageRe = "尊敬的用户您好，贵单位" + unitName + "的" + device + "于今天" + time + "恢复正常。";
            AliMessage aliMessage = new AliMessage();
            aliMessage.setId(UUIDUtils.get32UUID());
            if (templateCode.equals("SMS_214527311")){
                //水设备恢复
                aliMessage.setMessage(messageRe);
            }else if (templateCode.equals("SMS_213772600")) {
                //水设备报警
                aliMessage.setMessage(messageWaterAlarm);
            }else {
                //火报警
                aliMessage.setMessage(message);
            }

            aliMessage.setPhone(phone);
            aliMessage.setCreateTime(new Date());
            aliMessage.setMessageType("1");
            aliMessage.setUnitid(unitid);
            aliMessage.setBizId(sendSmsResponse.getBizId());
            aliMessage.setDeviceName(device);
            aliMessage.setReceiver(receiver);
            aliMessage.setUnitName(unitName);
            aliMessageMapper.insert(aliMessage);
            return 1;
        } else {
            System.out.println("=====fail=======");
            return 0;
        }
    }

    @Override
    public int sendAliVoice(String calledShowNumber, String calledNumber, String ttsCode, String device, String time,String unitid,String receiver, String unitName) {

        //设置超时时间-可自行调整
        System.setProperty("sun.net.client.defaultConnectTimeout", "10000");
        System.setProperty("sun.net.client.defaultReadTimeout", "10000");

        //初始化ascClient需要的几个参数
        final String product = "Dyvmsapi";//短信API产品名称（短信产品名固定，无需修改）

        final String domain = "dyvmsapi.aliyuncs.com";//短信API产品域名（接口地址固定，无需修改）
        //替换成你的AK
        final String accessKeyId = keyId;//你的accessKeyId
        final String accessKeySecret = keySecret;//你的accessKeySecret
        //初始化ascClient,暂时不支持多region（请勿修改）
        IClientProfile profile = DefaultProfile.getProfile("cn-hangzhou", accessKeyId, accessKeySecret);
        try {
            DefaultProfile.addEndpoint("cn-hangzhou", "cn-hangzhou", product, domain);
        } catch (ClientException e) {
            e.printStackTrace();
        }
        IAcsClient acsClient = new DefaultAcsClient(profile);

        //组装请求对象
        SingleCallByTtsRequest request = new SingleCallByTtsRequest();
        //必填-被叫显号,可在语音控制台中找到所购买的显号
        request.setCalledShowNumber(calledShowNumber);
        //必填-被叫号码
        request.setCalledNumber(calledNumber);
        //必填-Tts模板ID
        request.setTtsCode(ttsCode);
        //可选-当模板中存在变量时需要设置此值

        String param = "{\"device\":\"" + device + "\",\"time\":\"" + time + "\"}";

        request.setTtsParam(param);
        //可选-音量 取值范围 0--200
        request.setVolume(100);
        //可选-播放次数
        request.setPlayTimes(3);
        //可选-外部扩展字段,此ID将在回执消息中带回给调用方
        request.setOutId("yourOutId");
        //hint 此处可能会抛出异常，注意catch
        SingleCallByTtsResponse singleCallByTtsResponse = null;
        try {
            singleCallByTtsResponse = acsClient.getAcsResponse(request);
        } catch (ClientException e) {
            e.printStackTrace();
        }
        if (singleCallByTtsResponse.getCode() != null && singleCallByTtsResponse.getCode().equals("OK")) {
            System.out.println("=====success====");
            String message = "尊敬的用户你好，贵公司" +unitName+ device + "于今天" + time + "发生警情，请您及时确认处理。";
            AliMessage aliMessage = new AliMessage();
            aliMessage.setId(UUIDUtils.get32UUID());
            aliMessage.setMessage(message);
            aliMessage.setPhone(calledNumber);
            aliMessage.setCreateTime(new Date());
            aliMessage.setUnitid(unitid);
            aliMessage.setMessageType("2");
            aliMessage.setBizId(singleCallByTtsResponse.getCallId());
            aliMessage.setDeviceName(device);
            aliMessage.setReceiver(receiver);
            aliMessage.setUnitName(unitName);
            aliMessageMapper.insert(aliMessage);
            return 1;
        } else {
            System.out.println("=====fail=======");
            return 0;
        }
    }

    @Override
    public void batchSendAliVoice(String calledShowNumber, List<String> calledNumbers, String ttsCode, String device, String time,String unitid) {
        for (String calledNumber:calledNumbers) {
            sendAliVoice(calledShowNumber,calledNumber,ttsCode,device,time,unitid,"","");
        }

    }

    @Override
    public List<AliMessage> selectInfo(String s) {
        return this.baseMapper.selectInfo(s);
    }

    @Override
    public List<AliMessage> selectByCenter(List<String> ids) {
        return this.baseMapper.selectByCenter(ids);
    }

    @Override
    public PageVo<AliMessage> queryList(AliMessageDto aliMessageDto) {
        HashMap<String, Object> params = new HashMap<>(16);
        if(null !=aliMessageDto.getUnitId() ){
            params.put("unitId",aliMessageDto.getUnitId());
        }
        if(null !=aliMessageDto.getUnitIdList() && aliMessageDto.getUnitIdList().size()>0){
            params.put("unitIds",aliMessageDto.getUnitIdList());
        }
        if(null !=aliMessageDto.getMessageType()){
            params.put("messageType",aliMessageDto.getMessageType());
        }
        if(null !=aliMessageDto.getUnitName()){
            params.put("unitName",aliMessageDto.getUnitName());
        }
        params.put("beginDate",aliMessageDto.getBeginDate());
        params.put("endDate",aliMessageDto.getEndDate());
        Page page = new Page();
        // 设置当前页码
        page.setCurrent(aliMessageDto.getPage());
        // 设置页大小
        page.setSize(aliMessageDto.getLimit());

        return new PageVo<AliMessage>(this.baseMapper.queryList(page,params));
    }

    @Override
    public void updateAliMessage(String errmsg, String bizid) {
        UpdateWrapper<AliMessage> aliMessageUpdateWrapper = new UpdateWrapper<>();
        aliMessageUpdateWrapper.lambda().eq(AliMessage::getBizId,bizid);
        AliMessage aliMessage = new AliMessage();
        aliMessage.setSendStatus(errmsg);
        update(aliMessage,aliMessageUpdateWrapper);
    }

    @Override
    public void updateAliVoiceCall(String statusCode, String callId) {
        UpdateWrapper<AliMessage> aliMessageUpdateWrapper = new UpdateWrapper<>();
        aliMessageUpdateWrapper.lambda().eq(AliMessage::getBizId,callId);
        AliMessage aliMessage = new AliMessage();
        if (null==statusCode) {
            return;
        }
        if (statusCode.equals("200000") || statusCode.equals("200001")){
            aliMessage.setSendStatus("接听成功");
        }else {
            aliMessage.setSendStatus("未接听");
        }
        update(aliMessage,aliMessageUpdateWrapper);
    }

    @Override
    public void batchSendAliMessage(List<String> phones, String signName, String templateCode, String unitName, String device, String time,String unitid) {
        for (String phone:phones) {
            sendAliMessage(phone,signName,templateCode,unitName,device,time,unitid,"","");
        }
    }

    @Override
    public void sendAliMessageBatch(List<EmergencyStaff> emergencyStaffList, String signName, String templateCode, String device, String time,String componentStatus) {
        for (EmergencyStaff emergencyStaff : emergencyStaffList){
            if(isMobile(emergencyStaff.getMobile())){
                sendAliMessage(emergencyStaff.getMobile(),signName,templateCode,emergencyStaff.getUnitname(),device,time,emergencyStaff.getUnitid(),emergencyStaff.getUsername(),componentStatus);
            }
        }
    }
    public static boolean isMobile(String mobile) {
        String regex = "^((13[0-9])|(14[5,7,9])|(15([0-3]|[5-9]))|(16[5,6])|(17[0-8])|(18[0-9])|(19[1、5、8、9]))\\d{8}$";
        Pattern p = Pattern.compile(regex, Pattern.CASE_INSENSITIVE);
        Matcher m = p.matcher(mobile);
        return m.matches();
    }

    @Override
    public void sendAliVoiceBatch(String calledShowNumber, List<EmergencyStaff> emergencyStaffList, String ttsCode, String device, String time) {
        for (EmergencyStaff emergencyStaff : emergencyStaffList){
            sendAliVoice(calledShowNumber,emergencyStaff.getMobile(),ttsCode,device,time,emergencyStaff.getUnitid(),emergencyStaff.getUsername(),emergencyStaff.getUnitname());
        }
    }

    /**
     * 短信发送
     *
     * @param param        短信内容
     * @param phone        手机号
     * @param keyId        阿里云短信平台短息秘钥
     * @param keySecret    阿里云短信平台短息秘钥
     * @param signName     短信签名-可在短信控制台中找到
     * @param templateCode 短信模板-可在短信控制台中找到
     * @return
     */
    private SendSmsResponse sendSmsRequest(String param, String phone, String keyId, String keySecret, String signName, String templateCode) {
        //设置超时时间-可自行调整
        System.setProperty("sun.net.client.defaultConnectTimeout", "10000");
        System.setProperty("sun.net.client.defaultReadTimeout", "10000");

        //初始化ascClient需要的几个参数
        final String product = "Dysmsapi";//短信API产品名称（短信产品名固定，无需修改）

        final String domain = "dysmsapi.aliyuncs.com";//短信API产品域名（接口地址固定，无需修改）
        //替换成你的AK
        if (StringUtils.isBlank(keyId)) {
            keyId = accessKeyId;
        }
        final String accessKeyId = keyId;//你的accessKeyId

        if (StringUtils.isBlank(keySecret)) {
            keySecret = accessKeySecret;
        }
        final String accessKeySecret = keySecret;//你的accessKeySecret

        if (StringUtils.isBlank(signName)) {
            signName = accessSignName;
        }

        if (StringUtils.isBlank(templateCode)) {
            templateCode = accessTemplateCode;
        }

        //初始化ascClient,暂时不支持多region（请勿修改）
        IClientProfile profile = DefaultProfile.getProfile("cn-hangzhou", accessKeyId, accessKeySecret);

        try {
            DefaultProfile.addEndpoint("cn-hangzhou", "cn-hangzhou", product, domain);
        } catch (ClientException e) {
            e.printStackTrace();
        }

        IAcsClient acsClient = new DefaultAcsClient(profile);
        //组装请求对象
        SendSmsRequest request = new SendSmsRequest();
        //使用post提交
        request.setMethod(MethodType.POST);
        //必填:待发送手机号。支持以逗号分隔的形式进行批量调用，批量上限为1000个手机号码,批量调用相对于单条调用及时性稍有延迟,验证码类型的短信推荐使用单条调用的方式；发送国际/港澳台消息时，接收号码格式为00+国际区号+号码，如“0085200000000”
        request.setPhoneNumbers(phone);
        //必填:短信签名-可在短信控制台中找到
        request.setSignName(signName);
        //必填:短信模板-可在短信控制台中找到，发送国际/港澳台消息时，请使用国际/港澳台短信模版
        request.setTemplateCode(templateCode);

        request.setTemplateParam(param);

        //请求失败这里会抛ClientException异常
        SendSmsResponse sendSmsResponse = null;
        try {
            sendSmsResponse = acsClient.getAcsResponse(request);
            log.info("短信发送返回信息:" + sendSmsResponse.getMessage());
        } catch (ClientException e) {
            log.info("短信发送失败:" + e.getMessage());
            e.printStackTrace();
        }

        if ("OK".equals(sendSmsResponse.getCode())) {
            //请求成功
            AliMessage aliMessage = new AliMessage();
            aliMessage.setId(UUIDUtils.get32UUID());
            aliMessage.setMessage(param);
            aliMessage.setPhone(phone);
            aliMessage.setCreateTime(new Date());
            aliMessageMapper.insert(aliMessage);
            log.info("短信保存:" + aliMessage.getId());
        } else {
            log.info("短信保存失败:" + sendSmsResponse.getMessage());
        }
        return sendSmsResponse;
    }
}
